from rest_framework import serializers
import datetime, time, json, requests, pymysql
from random import randint
from django_redis import get_redis_connection
from django.db.models import Q, F, Max
from django.conf import settings

from merchants.models import *
from orders.models import *
from equity_mall.utils.sync_img_to_local import make_qrcode, make_qrcode1, make_qrcode5
from goods.models import *
from merchants.utils import create_contract_table
from equity_mall.utils.express_utils import KuaiDi100
from equity_mall.utils.utils import redis_scheme_token_wyh
from equity_mall.utils.qiniu_storage import pic_upload


class MerchantUserInfoSerializer(serializers.ModelSerializer):

    is_psbc_card_str = serializers.CharField(source='get_is_psbc_card_display', read_only=True)
    lucky_bag_description = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = MerchantUser
        fields = ['id', 'mobile', 'avatarUrl', 'nickName', 'auth_state', 'identification_name', 'identification_number', 'is_psbc_card', 'is_psbc_card_str',
                  'lucky_bag', 'lucky_bag_description']

    def get_lucky_bag_description(self, obj):
        return '''福袋获取方式：通过参与抽奖活动获取；
使用规则：
1.集满 50 个福袋后，即可发起提现申请。
2.每个福袋的价值为 0.1 元。
3.单次最低提现金额为 5 元（50 个福袋），没有最高限制。
4.单次提现 200 元以内默认提现提现至微信零钱，单次提现超过 200 元则提现至支付宝账户。
提现流程：
1.打开小程序，进入“我的福袋”页面；
2.输入提现金额，点击【立即提现】；
3.使用一分钱验证邮储银行卡，验卡成功后点击“点击继续提现”；
4.提现成功，提现金额将在 1-3 个工作日内到账用户微信零钱，如单次提现超过 200 元，需填写支付宝账户信息后提现至支付宝账户。
注意事项：
1.每个用户每天最多可提现 2 次；
2.参与活动的用户需完成实名认证；
3.若发现违规操作（如刷福袋、虚假交易等），平台有权取消其参与资格及福袋奖励。
特别声明：
1.福袋仅限于本平台内使用，不能提现至其他平台或兑换其他形式的奖励。
2.本活动最终解释权归平台所有，平台保留对活动规则的修改和最终解释权。
客服支持：如有任何疑问，请联系平台客服。'''


class MerchantBillListModelSerializer(serializers.ModelSerializer):

    receipts_time = serializers.DateTimeField(format="%Y-%m-%d", required=False)
    bill_state_str = serializers.CharField(source='get_bill_state_display', read_only=True)
    week_day = serializers.SerializerMethodField(read_only=True)
    day = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = MerchantBill
        fields = ['id', 'receipts_time', 'payable_amount', 'bill_state', 'bill_state_str', 'week_day', 'day']

    def get_week_day(self, obj):
        week_day_dict = {
            0: '星期一',
            1: '星期二',
            2: '星期三',
            3: '星期四',
            4: '星期五',
            5: '星期六',
            6: '星期天',
        }
        day = datetime.datetime.fromtimestamp(time.mktime(obj.receipts_time.timetuple())).weekday()
        return week_day_dict[day]

    def get_day(self, obj):
        return obj.receipts_time.strftime('%Y-%m-%d')[-2:]


class MerchantBillRetrieveModelSerializer(serializers.ModelSerializer):

    receipts_time = serializers.DateTimeField(format="%Y-%m-%d", required=False)
    settlement_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    bill_state_str = serializers.CharField(source='get_bill_state_display', read_only=True)
    bill_type_str = serializers.CharField(source='get_bill_type_display', read_only=True)
    account_number = serializers.SerializerMethodField(read_only=True)
    account_bank = serializers.SerializerMethodField(read_only=True)
    account_name = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = MerchantBill
        fields = ['id', 'receipts_time', 'payable_amount', 'bill_state', 'bill_state_str', 'order_id',
                  'account_name', 'account_bank', 'account_number', 'settlement_time', 'context', 'bill_type', 'bill_type_str']

    def get_account_number(self, obj):
        try:
            if obj.bill_state == 1:
                return str(obj.merchant.account_number)[:6] + '********' + str(obj.merchant.account_number)[-5:]
            else:
                return obj.account_number
        except:
            return ''

    def get_account_bank(self, obj):
        try:
            if obj.bill_state == 1:
                return obj.merchant.account_bank
            else:
                return obj.account_bank
        except:
            return ''

    def get_account_name(self, obj):
        try:
            if obj.bill_state == 1:
                return obj.merchant.account_name
            else:
                return obj.account_name
        except:
            return ''


class OrderGoodsSerializer(serializers.ModelSerializer):

    default_image = serializers.SerializerMethodField(read_only=True)
    name = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = OrderGoods
        fields = ('id', 'default_image', 'count', 'name', 'price')

    def get_default_image(self, obj):
        try:
            return obj.goods.default_image.url
        except Exception as e:
            return ''

    def get_name(self, obj):
        try:
            return obj.goods.name
        except Exception as e:
            return ''


class OrderInfoListModelSerializer(serializers.ModelSerializer):

    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    use_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    ordergoods_set = OrderGoodsSerializer(many=True)
    level_name = serializers.SerializerMethodField(read_only=True)
    state_str = serializers.CharField(source='get_state_display', read_only=True)
    order_species_str = serializers.CharField(source='get_order_species_display', read_only=True)

    class Meta:
        model = OrderInfo
        fields = ['id', 'create_time', 'order_id', 'ordergoods_set', 'total_price', 'level_name', 'use_time', 'state', 'state_str', 'total_count',
                  'order_species', 'order_species_str']

    def get_level_name(self, obj):
        try:
            return obj.level.name
        except Exception as e:
            return ''


class GoodsCouponsModelSerializer(serializers.ModelSerializer):

    status_str = serializers.CharField(source='get_status_display', read_only=True)
    coupons_id = serializers.SerializerMethodField(read_only=True)
    validity_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)

    class Meta:
        model = GoodsCoupons
        fields = ['id', 'status_str', 'status', 'coupons_id', 'validity_time']

    def get_coupons_id(self, obj):
        if obj.status == 1:
            return obj.coupons_id[:8] + '********'
        else:
            return obj.coupons_id


class OrderAddressModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = OrderAddress
        fields = ['id', 'receiver', 'place', 'mobile', 'province', 'city', 'district']


class ExpressPlanModelSerializer(serializers.ModelSerializer):

    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)

    class Meta:
        model = ExpressPlan
        fields = ('id', 'create_time', 'remark')


class ExpressModelSerializer(serializers.ModelSerializer):

    deliverystatus_str = serializers.CharField(source='get_deliverystatus_display', read_only=True)
    express_name = serializers.SerializerMethodField(read_only=True)
    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    expressplan_set = serializers.SerializerMethodField(read_only=True)
    deliverystatus = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = Express
        fields = ('id', 'deliverystatus', 'deliverystatus_str', 'express_number', 'express_name', 'create_time', 'expressplan_set')

    def get_deliverystatus(self, obj):
        try:
            if obj.deliverystatus in [0, 1, 5, 2, 6]:
                redis_conn = get_redis_connection("express_number")
                express_number_flag = redis_conn.get("express_number_%s" % obj.express_number)
                if not express_number_flag:
                    redis_conn.setex('express_number_%s' % obj.express_number, 21600, 1)
                    order = ExpressOrderRelevance.objects.filter(express_id=obj.id).first()
                    phone = OrderAddress.objects.filter(order_id=order.order_id).first()
                    if phone:
                        result = KuaiDi100().track(obj.express_type.express_type, obj.express_number, phone.mobile[-4:])
                    else:
                        result = KuaiDi100().track(obj.express_type.express_type, obj.express_number)
                    if result['status'] == '200':
                        obj.deliverystatus = result['state']
                        obj.save()
                        if obj.deliverystatus == 3:
                            try:
                                order = obj.order
                                user = order.user
                            except:
                                pass
                        for i in result['data']:
                            plan_data = {}
                            plan_data['express_id'] = obj.id
                            plan_data['create_time'] = i['time']
                            plan_data['remark'] = i['context']
                            ExpressPlan.objects.get_or_create(defaults=plan_data, create_time=i['time'], express_id=obj.id)
                        if str(obj.deliverystatus) == "3":
                            try:
                                sign_time = ExpressPlan.objects.filter(express_id=obj.id).aggregate(Max('create_time'))['create_time__max']
                                obj.sign_time = sign_time
                                obj.save()
                            except:
                                pass
                    else:
                        obj.deliverystatus = 9
                        obj.save()
                        ExpressPlan.objects.create(remark=result['message'], create_time=datetime.datetime.now(), express_id=obj.id)
            return obj.deliverystatus
        except:
            return obj.deliverystatus

    def get_expressplan_set(self, obj):
        try:
            expressplan_set = obj.expressplan_set.all().order_by('-create_time')
            return ExpressPlanModelSerializer(expressplan_set, many=True).data
        except:
            return []

    def get_express_name(self, obj):
        try:
            return obj.express_type.express_type_name
        except:
            return ''


class AfterSaleApplicationFormModelSerializer(serializers.ModelSerializer):

    form_status_str = serializers.CharField(source='get_form_status_display', read_only=True)
    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    refund_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    img_array = serializers.SerializerMethodField(read_only=True)
    reason = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = AfterSaleApplicationForm
        fields = ['id', 'form_status', 'form_status_str', 'create_time', 'description', 'refund_money', 'return_msg',
                  'refund_time', 'reason', 'img_array', 'application_num']

    def get_reason(self, obj):
        try:
            return obj.reason.name
        except:
            return ''

    def get_img_array(self, obj):
        data = []
        try:
            queryset = AfterSaleApplicationFormImg.objects.filter(applicationform_id=obj.id)
            for query in queryset:
                data.append(query.img.url)
        except:
            pass
        return data


class AfterSaleApplicationFormListModelSerializer(serializers.ModelSerializer):

    form_status_str = serializers.CharField(source='get_form_status_display', read_only=True)
    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    refund_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    img_array = serializers.SerializerMethodField(read_only=True)
    reason = serializers.SerializerMethodField(read_only=True)
    order = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = AfterSaleApplicationForm
        fields = ['id', 'form_status', 'form_status_str', 'create_time', 'description', 'refund_money', 'return_msg', 'refund_time', 'reason', 'img_array',
                  'application_num', 'order']

    def get_order(self, obj):
        data = {}
        data['id'] = ''
        data['merchant_name'] = ''
        data['order_id'] = ''
        data['default_image'] = ''
        data['goods_name'] = ''
        try:
            order = obj.order
            order_goods = OrderGoods.objects.filter(order_id=order.id).first()
            goods = order_goods.goods
            data['id'] = order.id
            data['merchant_name'] = order.merchant.name
            data['order_id'] = order.orderNum
            data['default_image'] = goods.default_image.url
            data['goods_name'] = goods.name
        finally:
            return data

    def get_reason(self, obj):
        try:
            return obj.reason.name
        except:
            return ''

    def get_img_array(self, obj):
        data = []
        try:
            queryset = AfterSaleApplicationFormImg.objects.filter(applicationform_id=obj.id)
            for query in queryset:
                data.append(query.img.url)
        except:
            pass
        return data


class AfterSaleApplicationFormRetrieveModelSerializer(serializers.ModelSerializer):

    form_status_str = serializers.CharField(source='get_form_status_display', read_only=True)
    reason_type_str = serializers.CharField(source='get_reason_type_display', read_only=True)
    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    refund_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    img_array = serializers.SerializerMethodField(read_only=True)
    reason = serializers.SerializerMethodField(read_only=True)
    order = serializers.SerializerMethodField(read_only=True)
    orderaddress = serializers.SerializerMethodField(read_only=True)
    number = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = AfterSaleApplicationForm
        fields = ['id', 'form_status', 'form_status_str', 'create_time', 'description', 'refund_money', 'return_msg', 'refund_time', 'reason', 'img_array',
                  'application_num', 'order', 'orderaddress', 'reason_type', 'reason_type_str', 'number']

    def get_number(self, obj):
        return 1

    def get_order(self, obj):
        data = {}
        data['id'] = ''
        data['merchant_name'] = ''
        data['default_image'] = ''
        data['total_price'] = ''
        data['goods_name'] = ''
        try:
            order = obj.order
            order_goods = OrderGoods.objects.filter(order_id=order.id).first()
            data['id'] = order.id
            data['merchant_name'] = order.merchant.name
            data['default_image'] = order_goods.goods.default_image.url
            data['total_price'] = order.total_price
            data['goods_name'] = order_goods.goods.name
        finally:
            return data

    def get_reason(self, obj):
        try:
            return obj.reason.name
        except:
            return ''

    def get_img_array(self, obj):
        data = []
        try:
            queryset = AfterSaleApplicationFormImg.objects.filter(applicationform_id=obj.id)
            for query in queryset:
                data.append(query.img.url)
        except:
            pass
        return data

    def get_orderaddress(self, obj):
        data = {}
        data['receiver'] = ''
        data['place'] = ''
        data['mobile'] = ''
        try:
            merchant = obj.order.merchant
            data['receiver'] = merchant.managerName
            data['place'] = merchant.store_address
            data['mobile'] = merchant.managermobile
        finally:
            return data


class OrderInfoRetrieveModelSerializer(serializers.ModelSerializer):

    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    state_str = serializers.CharField(source='get_state_display', read_only=True)
    ordergoods_set = OrderGoodsSerializer(many=True)
    goodscoupons_set = serializers.SerializerMethodField(read_only=True)
    level_name = serializers.SerializerMethodField(read_only=True)
    merchant_name = serializers.SerializerMethodField(read_only=True)
    customeruser_realname = serializers.SerializerMethodField(read_only=True)
    orderaddress = serializers.SerializerMethodField(read_only=True)
    express_info = serializers.SerializerMethodField(read_only=True)
    after_sale = serializers.SerializerMethodField(read_only=True)
    aftersaleapplicationform_id = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = OrderInfo
        fields = ['id', 'create_time', 'state_str', 'ordergoods_set', 'total_price', 'goodscoupons_set', 'reserved_mobile', 'level_name', 'merchant_name',
                  'customeruser_realname', 'state', 'order_type', 'orderaddress', 'express_info', 'order_id', 'after_sale', 'aftersaleapplicationform_id']

    def get_aftersaleapplicationform_id(self, obj):
        if obj.state == 5:
            after_sale = AfterSaleApplicationForm.objects.filter(order_id=obj.id).exclude(form_status=4).last()
            if after_sale:
                return after_sale.id
        return ''

    def get_after_sale(self, obj):
        try:
            after_sale = AfterSaleApplicationForm.objects.exclude(form_status=4).filter(order_id=obj.id).last()
            if after_sale:
                return AfterSaleApplicationFormModelSerializer(after_sale).data
            else:
                return {}
        except:
            return {}

    def get_express_info(self, obj):
        try:
            express_id_list = ExpressOrderRelevance.objects.filter(order_id=obj.id).values_list('express_id', flat=True)
            express_set = Express.objects.filter(id__in=list(express_id_list))
            return ExpressModelSerializer(express_set, many=True).data
        except:
            return []

    def get_orderaddress(self, obj):
        try:
            orderaddress = obj.orderaddress
            if orderaddress:
                return OrderAddressModelSerializer(orderaddress).data
            else:
                return {}
        except:
            return {}

    def get_customeruser_realname(self, obj):
        try:
            customeruser_realname = obj.customer_user.realname
            if customeruser_realname:
                return customeruser_realname
            else:
                return ''
        except:
            return ''

    def get_merchant_name(self, obj):
        try:
            return obj.merchant.name
        except:
            return ''

    def get_goodscoupons_set(self, obj):
        try:
            goodscoupons_set = obj.goodscoupons_set.all().order_by('status')
            return GoodsCouponsModelSerializer(goodscoupons_set, many=True).data
        except:
            return []

    def get_level_name(self, obj):
        try:
            return obj.level.name
        except:
            return ''


class MerchantImageSerializer(serializers.ModelSerializer):

    class Meta:
        model = MerchantImage
        fields = ['id', 'image']


class MerchantModelSerializer(serializers.ModelSerializer):

    is_online_str = serializers.CharField(source='get_is_online_display', read_only=True)
    level_name = serializers.SerializerMethodField(read_only=True)
    business_category_name = serializers.SerializerMethodField(read_only=True)
    open_work_time = serializers.DateTimeField(format="%H:%M", required=False)
    close_work_time = serializers.DateTimeField(format="%H:%M", required=False)
    merchantimage_set = MerchantImageSerializer(many=True)
    provincial_code = serializers.SerializerMethodField(read_only=True)
    region = serializers.SerializerMethodField(read_only=True)
    coupon_set = serializers.SerializerMethodField(read_only=True)
    merchant_home_qrcode = serializers.SerializerMethodField(read_only=True)
    is_mall = serializers.SerializerMethodField(read_only=True)
    is_mall_str = serializers.SerializerMethodField(read_only=True)
    contract_table = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = Merchant
        fields = ['id', 'is_online', 'is_online_str', 'name', 'short_name', 'managerName', 'wyfMerchantID', 'level_name',
                  'merchant_desc', 'business_category_name', 'business_category_id', 'close_work_time', 'open_work_time',
                  'store_logo_copy', 'merchantimage_set', 'managermobile', 'prov_name', 'city_name', 'district_name', 'store_address',
                  'longitude', 'latitude', 'region', 'provincial_code', 'coupon_set', 'merchant_home_qrcode', 'is_mall', 'is_mall_str',
                  'contract_table']

    def get_contract_table(self, obj):
        try:
            if obj.subject_type != 1:
                if not obj.contract_table:
                    url = 'https://manage.gdwxyf.com/internal/searchmerchantbyshopids.do'
                    body = {
                        'shopId': obj.ruiyinxinMerchantID,
                        'account': 'gdyouzheng'
                    }
                    response = requests.post(url=url, data=body)
                    result = response.json()
                    merchant_name = result['shopName']
                    merchant_other_5 = result['allchannelJson']['channel_sxf_tq']['merchant_other_5']
                    artifIdentity = result['artifIdentity']
                    licenceNo = result['licenceNo']
                    contract_table = create_contract_table(merchant_name, merchant_other_5, artifIdentity, licenceNo)
                    obj.contract_table = contract_table
                    obj.save()
                    return f'https://circle.sutpay.cn/{contract_table}'
                else:
                    return obj.contract_table.url
            else:
                return ''
        except Exception as e:
            print(e)
            return ''

    def get_is_mall(self, obj):
        try:
            if not obj.is_mall:
                return 0
            else:
                return obj.is_mall
        except:
            return 1

    def get_is_mall_str(self, obj):
        try:
            if not obj.is_mall:
                return '未上架'
            else:
                return obj.get_is_mall_display()
        except:
            return '未上架'

    def get_merchant_home_qrcode(self, obj):
        try:
            if not obj.merchant_home_url:
                redis_conn = get_redis_connection("scheme")
                access_token = redis_conn.get('wyh_access_token')
                if access_token is None:
                    access_token = redis_scheme_token_wyh()
                else:
                    access_token = access_token.decode()
                url = f'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={access_token}'
                body = {
                    "page": "pages/sqm_active_store/sqm_active_store",
                    "scene": f"id={obj.id}",
                    "is_hyaline": True
                }
                response = requests.post(url=url, json=body)
                try:
                    if response.json()['errcode'] != 0:
                        access_token = redis_scheme_token_wyh()
                        url = f'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={access_token}'
                        response = requests.post(url=url, json=body)
                except:
                    pass
                reslut = response.content
                common_qrcode_url = pic_upload(reslut)
                merchant_home_url = f'https://api.sutpay.com/customer/merchant_home/?id={obj.id}'
                # merchant_home_qrcode = f'youhuiquanyi/{obj.wyfMerchantID}/merchant_home.png'
                # common_qrcode_url = make_qrcode(obj.wyfMerchantID, merchant_home_url, merchant_home_qrcode)
                obj.merchant_home_qrcode = common_qrcode_url
                obj.merchant_home_url = merchant_home_url
                obj.save()
                return f'https://circle.sutpay.cn/{common_qrcode_url}'
            else:
                return obj.merchant_home_qrcode.url
        except:
            return ''

    def get_coupon_set(self, obj):
        return []

    def get_provincial_code(self, obj):
        data = []
        try:
            if obj.prov_code:
                data.append(obj.prov_code)
                data.append(obj.city_code)
                data.append(obj.district_code)
        except:
            pass
        return data

    def get_region(self, obj):
        data = []
        try:
            if obj.prov_name:
                data.append(obj.prov_name)
                data.append(obj.city_name)
                data.append(obj.district_name)
        except:
            pass
        return data

    def get_level_name(self, obj):
        try:
            return obj.level.name
        except Exception as e:
            return ''

    def get_business_category_name(self, obj):
        try:
            return obj.business_category.name
        except Exception as e:
            return ''


class MerchantBusinessCategoryModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = MerchantBusinessCategory
        fields = ['id', 'name']


class WaivePaymentActivityModelSerializer(serializers.ModelSerializer):

    activity_name = serializers.SerializerMethodField(read_only=True)
    description = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = WaivePaymentMerchant
        fields = ['id', 'activity_name', 'description']

    def get_activity_name(self, obj):
        try:
            return obj.waivepaymentactivity.activity_name
        except:
            return ''

    def get_description(self, obj):
        try:
            return obj.waivepaymentactivity.description
        except:
            return ''


class WaivePaymentMerchantListModelSerializer(serializers.ModelSerializer):

    payment_state_str = serializers.CharField(source='get_payment_state_display', read_only=True)
    activity_name = serializers.SerializerMethodField(read_only=True)
    payment_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    received_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    # amount = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = WaivePaymentMerchant
        fields = ['id', 'activity_name', 'payment_state', 'payment_state_str', 'amount', 'payment_time', 'received_time']

    def get_activity_name(self, obj):
        try:
            return obj.waivepaymentactivity.activity_name
        except:
            return ''

    # def get_amount(self, obj):
    #     try:
    #         return f'¥{obj.amount}'
    #     except:
    #         return ''


class WaivePaymentMerchantRetrieveModelSerializer(serializers.ModelSerializer):

    payment_state_str = serializers.CharField(source='get_payment_state_display', read_only=True)
    payment_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    level_name = serializers.SerializerMethodField(read_only=True)
    order_info = serializers.SerializerMethodField(read_only=True)
    amount = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = WaivePaymentMerchant
        fields = ['id', 'payment_state', 'payment_state_str', 'return_msg', 'account', 'name', 'payment_time', 'amount',
                  'level_name', 'order_info', 'company_mobile']

    def get_amount(self, obj):
        try:
            return f'¥{obj.amount}'
        except:
            return ''

    def get_level_name(self, obj):
        try:
            return obj.merchant.level.name
        except:
            return ''

    def get_order_info(self, obj):
        data = {}
        data['trade_money'] = ''
        data['trade_type_str'] = ''
        data['trade_time'] = ''
        try:
            is_hit_order = obj.waivepaymentorder_set.all().filter(is_hit=1).first()
            data['trade_money'] = f'¥{is_hit_order.trade_money}'
            data['trade_type_str'] = is_hit_order.get_trade_type_display()
            data['trade_time'] = is_hit_order.trade_time_end.strftime('%Y-%m-%d %H:%M:%S')
        except:
            pass
        return data


class MerchantBindCardOrderRetrieveModelSerializer(serializers.ModelSerializer):

    order_status_str = serializers.CharField(source='get_order_status_display', read_only=True)

    class Meta:
        model = MerchantBindCardOrder
        fields = ('id', 'order_status', 'order_status_str')


class MerchantEightEightDrawListModelSerializer(serializers.ModelSerializer):

    state_str = serializers.CharField(source='get_state_display', read_only=True)
    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    received_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    prize_name = serializers.SerializerMethodField(read_only=True)
    win_type = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = MerchantEightEightDraw
        fields = ('id', 'amount', 'state', 'state_str', 'create_time', 'received_time', 'return_msg', 'win_type', 'prize_name')

    def get_prize_name(self, obj):
        prize = MerchantEightEightActivityPrize.objects.get(id=obj.win_type)
        return prize.name

    # def get_amount(self, obj):
    #     prize = MerchantEightEightActivityPrize.objects.get(id=obj.win_type)
    #     if prize.prize_type == 1:
    #         return obj.amount
    #     else:
    #         return prize.prize_name

    def get_win_type(self, obj):
        prize = MerchantEightEightActivityPrize.objects.get(id=obj.win_type)
        return prize.prize_type


class GoodsListModelSerializer(serializers.ModelSerializer):

    # is_launched = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = Goods
        fields = ('id', 'name', 'default_image', 'price', 'sales', 'is_launched')


class GoodsRetrieveModelSerializer(serializers.ModelSerializer):

    goodsimage_set = serializers.SerializerMethodField(read_only=True)
    merchant_name = serializers.SerializerMethodField(read_only=True)
    desc_detail = serializers.SerializerMethodField(read_only=True)
    market_code = serializers.SerializerMethodField(read_only=True)
    business_no = serializers.SerializerMethodField(read_only=True)
    reject_reason = serializers.SerializerMethodField(read_only=True)
    store_address = serializers.SerializerMethodField(read_only=True)
    goods_is_launched = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = Goods
        fields = ('id', 'name', 'default_image', 'price', 'sales', 'goodsimage_set', 'desc_detail', 'market_price', 'merchant_name',
                  'manufacturer', 'specifications', 'stock', 'business_no', 'caption', 'is_launched', 'reject_reason', 'is_launched',
                  'market_code', 'store_address', 'goods_is_launched', 'desc_pack')

    def get_goods_is_launched(self, obj):
        try:
            user = self.context.get('user', None)
            launchedgoods = LaunchedGoods.objects.filter(level_id__isnull=True, goods_id=obj.id).first()
            if launchedgoods:
                return launchedgoods.is_launched
            else:
                launchedgoods_data = {}
                launchedgoods_data['level_id'] = None
                launchedgoods_data['goods_id'] = obj.id
                launchedgoods_data['is_launched'] = 0
                launchedgoods_data['name'] = obj.name
                launchedgoods_data['category_id'] = 1
                launchedgoods_data['stock'] = 0
                launched_goods, create = LaunchedGoods.objects.get_or_create(defaults=launchedgoods_data, level_id=None, goods_id=obj.id)
                return 0
        except:
            return 0

    def get_reject_reason(self, obj):
        try:
            if obj.is_launched == 3:
                applyment = obj.goodsmodifyapplyment_set.all().filter(applyment_status=3).last()
                return applyment.reject_reason
            else:
                return ''
        except:
            return ''

    def get_store_address(self, obj):
        try:
            return obj.merchant.store_address
        except:
            return ''

    def get_goodsimage_set(self, obj):
        data = []
        try:
            goodsimage_set = obj.goodsimage_set.all()
            for goodsimage in goodsimage_set:
                data.append(goodsimage.image.url)
        except:
            pass
        return data

    def get_merchant_name(self, obj):
        try:
            return obj.merchant.name
        except:
            return ''

    def get_business_no(self, obj):
        try:
            return obj.merchant.wyfMerchantID
        except:
            return ''

    def get_desc_detail(self, obj):
        try:
            return json.loads(obj.desc_detail.replace("'", '"'))
        except:
            return obj.desc_detail

    def get_market_code(self, obj):
        try:
            if not obj.market_url:
                redis_conn = get_redis_connection("scheme")
                access_token = redis_conn.get('wyh_access_token')
                if access_token is None:
                    access_token = redis_scheme_token_wyh()
                else:
                    access_token = access_token.decode()
                url = f'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={access_token}'
                body = {
                    "page": "pages/pro_detail/pro_detail",
                    "scene": f"goods_id={obj.id}&level_id=",
                    "is_hyaline": True
                }
                response = requests.post(url=url, json=body)
                try:
                    if response.json()['errcode'] != 0:
                        access_token = redis_scheme_token_wyh()
                        url = f'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={access_token}'
                        response = requests.post(url=url, json=body)
                except:
                    pass
                reslut = response.content
                market_code = pic_upload(reslut)
                market_url =f'https://qrcode.sutpay.com/business/market_goods/?goods_id={obj.id}&level_id='
                # merchant_home_qrcode = f'youhuiquanyi/{obj.wyfMerchantID}/merchant_home.png'
                # common_qrcode_url = make_qrcode(obj.wyfMerchantID, merchant_home_url, merchant_home_qrcode)
                obj.market_url = market_url
                obj.market_code = market_code
                obj.save()
                return f'https://circle.sutpay.cn/{market_code}'

                # market_url = f'https://qrcode.sutpay.com/business/market_goods/?goods_id={obj.id}&level_id='
                # market_code = make_qrcode1(obj.merchant.wyfMerchantID, market_url, None)
                # obj.market_url = market_url
                # obj.market_code = market_code
                # obj.save()
                # return f'https://circle.sutpay.cn/{market_code}'
            else:
                return obj.market_code.url
        except:
            return ''


class ExpressTypeModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = ExpressType
        fields = ('id', 'express_type_name', 'logo')


class MerchantMonthlyBillListModelSerializer(serializers.ModelSerializer):

    class Meta:
        model =  MerchantMonthlyBill
        fields = ('id', 'bill_name', 'bill_time', 'order_amount')


class MerchantMonthlyBillRetrieveModelSerializer(serializers.ModelSerializer):

    class Meta:
        model =  MerchantMonthlyBill
        fields = ('id', 'bill_name', 'bill_time', 'order_amount', 'order_count', 'separate_amount', 'restitution_amount',
                  'settlement_amount', 'bill_file')


class ExpressListModelSerializer(serializers.ModelSerializer):

    express_type = serializers.SerializerMethodField(read_only=True)
    express_type_logo = serializers.SerializerMethodField(read_only=True)
    address = serializers.SerializerMethodField(read_only=True)
    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    sign_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    deliverystatus_str = serializers.CharField(source='get_deliverystatus_display', read_only=True)
    expressplan_set = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = Express
        fields = ('id', 'express_type_id', 'express_type', 'express_type_logo', 'express_number', 'create_time', 'sign_time',
                  'deliverystatus', 'deliverystatus_str', 'address', 'expressplan_set')

    def get_expressplan_set(self, obj):
        try:
            expressplan_set = obj.expressplan_set.all().order_by('-create_time')
            return ExpressPlanModelSerializer(expressplan_set, many=True).data
        except:
            return []

    def get_address(self, obj):
        data = {}
        try:
            order = ExpressOrderRelevance.objects.filter(express_id=obj.id).first().order
            if obj.nature == 1:
                address = OrderAddress.objects.filter(order_id=order.id).first()
                data['receiver'] = address.receiver
                data['place'] = address.place
                data['mobile'] = address.mobile
            else:
                merchant = order.merchant
                data['receiver'] = merchant.managerName
                data['place'] = merchant.store_address
                data['mobile'] = merchant.managermobile
        except:
            pass
        return data

    def get_express_type(self, obj):
        try:
            return obj.express_type.express_type_name
        except:
            return ''

    def get_express_type_logo(self, obj):
        try:
            return obj.express_type.logo
        except:
            return ''


class ExpressRetrieveModelSerializer(serializers.ModelSerializer):

    express_type = serializers.SerializerMethodField(read_only=True)
    express_type_logo = serializers.SerializerMethodField(read_only=True)
    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    sign_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    deliverystatus_str = serializers.CharField(source='get_deliverystatus_display', read_only=True)
    expressplan_set = serializers.SerializerMethodField(read_only=True)
    order_set = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = Express
        fields = ('id', 'express_type_id', 'express_type', 'express_type_logo', 'express_number', 'create_time', 'sign_time',
                  'deliverystatus', 'deliverystatus_str', 'expressplan_set', 'order_set')

    def get_order_set(self, obj):
        try:
            order_id_list = obj.expressorderrelevance_set.all().values_list('order_id', flat=True)
            order_set = OrderInfo.objects.filter(id__in=list(order_id_list))
            return OrderInfoListModelSerializer(order_set, many=True).data
        except:
            return []

    def get_expressplan_set(self, obj):
        try:
            expressplan_set = obj.expressplan_set.all().order_by('-create_time')
            return ExpressPlanModelSerializer(expressplan_set, many=True).data
        except:
            return []

    def get_express_type(self, obj):
        try:
            return obj.express_type.express_type_name
        except:
            return ''

    def get_express_type_logo(self, obj):
        try:
            return obj.express_type.logo
        except:
            return ''


class MerchantBankQRCodeRetrieveModelSerializer(serializers.ModelSerializer):

    merchant = serializers.SerializerMethodField(read_only=True)
    qrcode = serializers.SerializerMethodField(read_only=True)
    bind_number = serializers.SerializerMethodField(read_only=True)
    update_time = serializers.SerializerMethodField(read_only=True)
    draw_data = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = MerchantBankQRCode
        fields = ['id', 'merchant', 'code_id', 'qrcode', 'link', 'bind_number', 'update_time', 'parent_code_id', 'draw_data']

    def get_draw_data(self, obj):
        data = {}
        data['is_draw'] = 1
        data['id'] = ''
        # business_no = obj.business_no
        # mobile = obj.merchant.managermobile
        # conn = pymysql.connect(host=settings.DATABASES['open']['HOST'],
        #                        port=settings.DATABASES['open']['PORT'],
        #                        database=settings.DATABASES['open']['NAME'],
        #                        user=settings.DATABASES['open']['USER'],
        #                        password=settings.DATABASES['open']['PASSWORD'])
        # cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        # try:
        #     sql = f'''
        #     SELECT * FROM (SELECT encouragemerchant_id FROM tb_m_encourage_draw WHERE label=1 AND business_no="{business_no}")AS c LEFT JOIN (SELECT a.*,b.mobile FROM (SELECT id,business_no,merchant_user_id FROM tb_m_encourage_merchant WHERE business_no="{business_no}")AS a LEFT JOIN (SELECT id,mobile FROM tb_m_merchant_user)AS b ON a.merchant_user_id=b.id)AS d ON c.encouragemerchant_id=d.id;
        #     '''
        #     cursor.execute(sql)
        #     row = cursor.fetchone()
        #     if row:
        #         if mobile == row['mobile']:
        #             data['is_draw'] = 1
        #             data['id'] = row['id']
        # finally:
        #     cursor.close()
        #     conn.close()
        return data


    def get_merchant(self, obj):
        data = {}
        data['merchant_name'] = ''
        data['business_no'] = ''
        data['level_name'] = ''
        try:
            merchant = obj.merchant
            level = obj.level
            data['merchant_name'] = merchant.name
            data['business_no'] = merchant.wyfMerchantID
            data['level_name'] = level.name
        except:
            pass
        return data

    def get_qrcode(self, obj):
        try:
            if not obj.qrcode:
                link = obj.link
                url = 'https://partner.douyinpay.com/api/merchant/getBankSubQrCodeValue'
                body = {
                    "code_id": obj.code_id,
                    "sign": link.replace(f'https://partner.douyinpay.com/external/bankcode?code_id={obj.code_id}&sign=', '')
                }
                response = requests.post(url=url, json=body)
                result = response.json()
                code_url = result['code_url']
                parent_code_id = result['parent_code_id']
                qrcode = make_qrcode5(obj.code_id, code_url, None)
                obj.qrcode = qrcode
                obj.parent_code_id = parent_code_id
                obj.save()
                return f'https://circle.sutpay.cn/{qrcode}'
            else:
                return obj.qrcode.url
        except:
            return ''

    def get_bind_number(self, obj):
        data = {}
        data['total_number'] = 0
        data['total_first_number'] = 0
        data['last_month_number'] = 0
        data['last_month_first_number'] = 0
        data['this_month_number'] = 0
        data['this_month_first_number'] = 0
        data['yesterday_number'] = 0
        data['yesterday_first_number'] = 0
        try:
            # today = datetime.datetime.now()
            # yesterday = today + datetime.timedelta(-1)
            # yesterday_begin = yesterday.strftime("%Y-%m-%d 00:00:00")
            # yesterday_end = yesterday.strftime("%Y-%m-%d 23:59:59")
            # last_month_begin = (today.replace(day=1) + datetime.timedelta(-1)).replace(day=1).strftime("%Y-%m-%d 00:00:00")
            # last_month_end = (today.replace(day=1) + datetime.timedelta(-1)).strftime("%Y-%m-%d 23:59:59")
            # this_month_begin = today.replace(day=1).strftime("%Y-%m-%d 00:00:00")
            # this_month_end = today.strftime("%Y-%m-%d 23:59:59")
            # total_number = MerchantBankQRCodeBindData.objects.filter(merchant_id=obj.merchant_id).count()
            # total_first_number = MerchantBankQRCodeBindData.objects.filter(merchant_id=obj.merchant_id, is_first=1).count()
            # last_month_number = MerchantBankQRCodeBindData.objects.filter(merchant_id=obj.merchant_id, bind_time__gte=last_month_begin, bind_time__lte=last_month_end).count()
            # last_month_first_number = MerchantBankQRCodeBindData.objects.filter(merchant_id=obj.merchant_id, is_first=1, bind_time__gte=last_month_begin, bind_time__lte=last_month_end).count()
            # this_month_number = MerchantBankQRCodeBindData.objects.filter(merchant_id=obj.merchant_id, bind_time__gte=this_month_begin, bind_time__lte=this_month_end).count()
            # this_month_first_number = MerchantBankQRCodeBindData.objects.filter(merchant_id=obj.merchant_id, is_first=1, bind_time__gte=this_month_begin, bind_time__lte=this_month_end).count()
            # yesterday_number = MerchantBankQRCodeBindData.objects.filter(merchant_id=obj.merchant_id, bind_time__gte=yesterday_begin, bind_time__lte=yesterday_end).count()
            # yesterday_first_number = MerchantBankQRCodeBindData.objects.filter(merchant_id=obj.merchant_id, is_first=1, bind_time__gte=yesterday_begin, bind_time__lte=yesterday_end).count()
            # data['total_number'] = total_number
            # data['total_first_number'] = total_first_number
            # data['last_month_number'] = last_month_number
            # data['last_month_first_number'] = last_month_first_number
            # data['this_month_number'] = this_month_number
            # data['this_month_first_number'] = this_month_first_number
            # data['yesterday_number'] = yesterday_number
            # data['yesterday_first_number'] = yesterday_first_number
            data['total_number'] = obj.total_number
            data['total_first_number'] = obj.total_first_number
        except:
            pass
        return data

    def get_update_time(self,obj):
        try:
            instance = MErchantBankQPCodeStatistics.objects.aggregate(Max('bind_time'))
            if instance:
                return instance['bind_time__max'].strftime("%Y-%m-%d")
            else:
                return ''
        except:
            return ''


class OrderGoodsCommentFileModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = OrderGoodsCommentFile
        fields = ('id', 'file', 'file_type')


class GoodsCommentModelSerializer(serializers.ModelSerializer):

    ordergoodscommentfile_set = OrderGoodsCommentFileModelSerializer(many=True)
    comment_time = serializers.DateTimeField(format="%Y-%m-%d", required=False)
    username = serializers.SerializerMethodField(read_only=True)
    avatar = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = OrderGoods
        fields = ('id', 'is_commented', 'comment', 'ordergoodscommentfile_set',
                  'comment_time', 'is_anonymous', 'avatar', 'username')

    def get_username(self, obj):
        try:
            if obj.is_anonymous == 1:
                return '匿名买家'
            else:
                return obj.order.customeruservice.username
        except:
            return '匿名买家'

    def get_avatar(self, obj):
        try:
            if obj.is_anonymous == 1:
                return 'https://jinjian.sutpay.cn/image/wyh_img101.png'
            else:
                return obj.order.customeruservice.avatar
        except:
            return 'https://jinjian.sutpay.cn/image/wyh_img101.png'